<?php
/**
 * Class MyProxy
 * @method editNews(int $newId)
 * @method delNews
 */
class MyProxy
{
    private $myObject;//操作对象类
    private $aspectObject;//切面类
    /**
     * 构造函数
     * @param $obj
     */
    function __construct($obj,$aspectObject)
    {
        $this->myObject = $obj;
        $this->aspectObject = $aspectObject;
    }
    public function __call($name, $arguments)
    {
        $c = new ReflectionClass($this->myObject);
        if ($c->hasMethod($name)){
            $method = $c->getMethod($name);//业务方法method
            $this->invokeAdvice($name, 'before');
            $res = $method->invoke($this->myObject,...$arguments);
            $this->invokeAdvice($name, 'after');
        }
        return false;
    }
    function invokeAdvice(string $methodName, string $advice){//运行通知
        if (!$this->aspectObject->isJointPoint($methodName)){
            return;
        }
        $asp = new ReflectionClass($this->aspectObject);//切面反射对象
        $aspMethods = $asp->getMethods(ReflectionMethod::IS_PUBLIC);//获取所有方法
        foreach ($aspMethods as $aspMethod){
            if (preg_match("/$advice/i", $aspMethod->getDocComment())){
                $aspMethod->invoke($this->aspectObject);//执行before方法
            }
        }
    }
}